<template>
  <input
    ref="inputRef"
    class="excel-upload-input"
    type="file"
    accept=".xlsx, .xls"
    @change="handleClick"
  />
  <div class="drop flex" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover">
    <span>拖拽到此处上传</span>
    <el-button :loading="loading" type="primary" @click="handleUpload"> 点击上传excel </el-button>
  </div>
</template>

<script setup>
import { ElMessage } from 'element-plus'
import { read, utils } from 'xlsx'
import { isExcel } from '@/utils/regexp'

const props = defineProps({
  beforeUpload: Function,
  onSuccess: Function,
})

const inputRef = ref(null)
const loading = ref(false)
const excelData = ref({
  header: null,
  results: null,
})

function handleDrop(e) {
  e.stopPropagation()
  e.preventDefault()
  if (loading.value) return

  const files = e.dataTransfer.files
  if (files.length !== 1) {
    return ElMessage.error('只支持上传一个文件')
  }

  const rawFile = files[0]
  if (!isExcel(rawFile.name)) {
    return ElMessage.error('只支持上传 .xlsx, .xls, .csv后缀类型的文件')
  }
  upload(rawFile)
  e.stopPropagation()
  e.preventDefault()
}

function handleDragover(e) {
  e.stopPropagation()
  e.preventDefault()
  e.dataTransfer.dropEffect = 'copy'
}

function handleUpload() {
  inputRef.value.click()
}

function handleClick(e) {
  const files = e.target.files
  const rawFile = files[0]
  if (!rawFile) return

  upload(rawFile)
}

function upload(rawFile) {
  // FIXME: can't select the same excel
  inputRef.value = null
  const beforeUpload = props.beforeUpload
  if (!beforeUpload) {
    readerData(rawFile)
    return
  }
  const before = beforeUpload(rawFile)
  before && readerData(rawFile)
}

function readerData(rawFile) {
  ElMessage.success(`文件名是：${rawFile.name}`)
  loading.value = true
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onload = (e) => {
      const data = e.target.result
      const workbook = read(data, { type: 'array' })
      const firstSheetName = workbook.SheetNames[0]
      const worksheet = workbook.Sheets[firstSheetName]
      const header = getHeaderRow(worksheet)
      const results = utils.sheet_to_json(worksheet)
      generateData({ header, results })
      loading.value = false
      resolve()
    }
    reader.readAsArrayBuffer(rawFile)
  })
}

function getHeaderRow(sheet) {
  const headers = []
  const range = utils.decode_range(sheet['!ref'])
  let C
  const R = range.s.r
  /* start in the first row */
  for (C = range.s.c; C <= range.e.c; ++C) {
    /* walk every column in the range */
    const cell = sheet[utils.encode_cell({ c: C, r: R })]
    /* find the cell in the first row */
    let hdr = 'UNKNOWN ' + C // <-- replace with your desired default
    if (cell && cell.t) hdr = utils.format_cell(cell)
    headers.push(hdr)
  }
  return headers
}

function generateData({ header, results }) {
  const onSuccess = props.onSuccess
  excelData.value = { header, results }
  onSuccess && onSuccess({ header, results })
}
</script>

<style scoped lang="scss">
.excel-upload-input {
  display: none;
  z-index: -9999;
}
.drop {
  justify-content: center;
  flex-direction: column;
  border: 1px dashed var(--el-border-color);
  height: 160px;
  margin: 0 auto;
  font-size: 24px;
  border-radius: 8px;
  text-align: center;
  color: #bbb;
  position: relative;
  &:hover {
    border: 1px dashed var(--el-color-primary);
  }
  span {
    margin-bottom: $space-medium-s;
  }
}
</style>
